package cn.sccdlg.crawler.jd.util;

import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.util.EntityUtils;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.UUID;

/**
 * @author RaoShuang
 * @emil 991207823@qq.com
 * @date 2020/11/29 22:15
 * HttpClient使用工具类
 */
@Component
public class HttpUtils {
    private PoolingHttpClientConnectionManager pcm;

    public HttpUtils() {
        this.pcm = new PoolingHttpClientConnectionManager();
        // 设置最大连接数
        this.pcm.setMaxTotal(100);
        // 设置每个主机的最大连接数
        this.pcm.setDefaultMaxPerRoute(10);
    }

    /**
     * 根据请求网址下载页面数据
     * @param url 访问url
     * @return
     */
    public String doGetHtml(String url) {
        //获取HttpClient对象
        CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(this.pcm).build();
        //创建httpGet请求对象，设置url地址
        HttpGet httpGet = new HttpGet(url);
        //设置请求信息
        httpGet.setConfig(this.getConfig());
        //设置请求头，伪装成浏览器，避免无法抓取商品页面数据。设置请求Request Headers中的User-Agent
        httpGet.addHeader("User-Agent","Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) " +
                "AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Mobile Safari/537.36");

        CloseableHttpResponse response = null;
        try {
            //使用httpClient发起请求，获取响应
            response = httpClient.execute(httpGet);
            //解析响应，返回结果
            if (response.getStatusLine().getStatusCode() == 200) {
                //判断响应体Entity是否不为空
                if (response.getEntity() != null) {
                    String content = EntityUtils.toString(response.getEntity(), "utf8");
                    return content;
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //关闭response
            closeResponse(response);
        }
        // 没有数据返回空串
        return "";
    }

    /**
     * 设置请求信息
     * @return
     */
    private RequestConfig getConfig() {
        //创建连接的最长时间，单位毫秒
        RequestConfig config = RequestConfig.custom().setConnectTimeout(1000)
                //设置获取连接的最长时间，单位毫秒
                .setConnectionRequestTimeout(500)
                //设置数据传输的最长时间，单位毫秒
                .setSocketTimeout(10000)
                .build();
        return config;
    }

    /**
     * 下载图片
     * @param url 访问路径url
     * @return 图片名称
     */
    public String doGetImage(String url) {
        //获取HttpClient对象
        CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(this.pcm).build();
        //创建httpGet请求对象，设置url地址
        HttpGet httpGet = new HttpGet(url);
        //设置请求信息
        httpGet.setConfig(this.getConfig());
        CloseableHttpResponse response = null;
        try {
            //使用httpClient发起请求，获取响应
            response = httpClient.execute(httpGet);
            //解析响应，返回结果
            if (response.getStatusLine().getStatusCode() == 200) {
                //判断响应体Entity是否不为空，不是空下载图片
                if (response.getEntity() != null) {
                    String picName = getImagesPathToSave(url, response);
                    return picName;
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            closeResponse(response);
        }
        return "";
    }

    /**
     * 下载实际图片并返回重命名的图片名
     * @param url 访问地址
     * @param response
     * @return 图片名称
     * @throws IOException
     */
    private String getImagesPathToSave(String url, CloseableHttpResponse response) throws IOException {
        //获取图片的后缀
        String extName = url.substring(url.lastIndexOf("."));
        //创建图片名，重命名图片
        String picName = UUID.randomUUID().toString()+ extName;
        //保存图片到本地指定位置
        String imagesPath = "D:\\Users\\HASEE\\DemoProject\\sccdlg-crawler-jd\\images\\";
        //判断目录是否存在，不存在则创建
        File file = new File(imagesPath);
        if (!file.exists()) {
            file.mkdirs();
        }
        OutputStream out = new FileOutputStream(new File(imagesPath + picName));
        response.getEntity().writeTo(out);
        //返回图片名称
        return picName;
    }

    /**
     * 关闭response
     * @param response
     */
    private void closeResponse(CloseableHttpResponse response) {
        if (response != null) {
            try {
                response.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

}
